package com.jhx.common.http;

import android.app.Activity;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.text.TextUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import me.foji.lifecyclebinder.LifeCycleBinder;
import me.foji.lifecyclebinder.OnLifeCycleChangedListener;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * 请求帮助类
 *
 * @author jack 2017-05-05 17:15
 */
public class HttpRequest implements OnLifeCycleChangedListener {
    private String mGroupTag;
    private List<Call> mCallList = new ArrayList<>();
    private static volatile HttpRequest sHttpRequest;
    /**
     * 缓存当前进行中的请求
     */
    private static Map<String, Call> mCallMap;
    /**
     * 一组请求
     */
    private static Map<String, List<Call>> mListMap;
    private Activity mActivity;

    public static HttpRequest getRequest() {
        if (sHttpRequest == null) {
            synchronized (HttpRequest.class) {
                if (sHttpRequest == null) {
                    sHttpRequest = new HttpRequest();
                }
            }
        }
        return sHttpRequest;
    }

    private HttpRequest() {
        mCallMap = new HashMap<>();
        mListMap = new HashMap<>();
    }

    /**
     * 为一组请求设置Tag
     * 比如：一个fragment,一个activity
     *
     * @param tagName
     * @return
     */
    private void setGroupTag(String tagName) {
        mGroupTag = tagName;
        if (!mListMap.containsKey(tagName)) {
            mListMap.put(tagName, mCallList);
        } else {
            mCallList = mListMap.get(tagName);
        }
    }

    public <T> void start(Call<HttpResponse<T>> call, ResponseCallback mCallback) {
        start(call, true, mCallback);
    }

    /**
     * get请求
     *
     * @param call      请求的call
     * @param mCallback 请求回调
     * @param showError 是否显示统一的错误提示
     */
    public <T> void start(Call<HttpResponse<T>> call, boolean showError, ResponseCallback mCallback) {
        final HttpCallback<T> httpCallback = new HttpCallback(mActivity, mCallback, showError);
        call.enqueue(new Callback<HttpResponse<T>>() {
            @Override
            public void onResponse(Call<HttpResponse<T>> call, Response<HttpResponse<T>> response) {
                String url = call.request().url().toString();
                mCallList.remove(call);
                mCallMap.remove(url);
                httpCallback.onResponse(url, response);
            }

            @Override
            public void onFailure(Call<HttpResponse<T>> call, Throwable t) {
                String url = call.request().url().toString();
                mCallList.remove(call);
                mCallMap.remove(url);
                httpCallback.onFailure(call.request().url().toString(), t);
            }
        });
        mCallList.add(call);
        putCall(call.request().url().toString(), call);
    }

    /**
     * 添加请求到缓存
     *
     * @param url
     * @param call
     */
    private void putCall(String url, Call call) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        synchronized (mCallMap) {
            mCallMap.put(url, call);
        }
    }

    /**
     * 取消一组请求
     *
     * @param url 需要取消请求的url
     */
    public void cancelRequest(String url) {
        synchronized (mCallMap) {
            if (mCallMap.containsKey(url)) {
                mCallMap.get(url).cancel();
                mCallMap.remove(url);
            }
        }
    }

    public HttpRequest autoRecycle(Activity activity) {
        if(activity != null) {
            setGroupTag(activity.getClass().getName());
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && !activity.isDestroyed()) {
                LifeCycleBinder.bind(activity, this);
            }
            mActivity = activity;
        }
        return this;
    }

    public HttpRequest autoRecycle(Fragment fragment) {
        if(fragment != null) {
            setGroupTag(fragment.getClass().getName());
            LifeCycleBinder.bind(fragment, this);
            mActivity = fragment.getActivity();
        }
        return this;
    }

    @Override
    public void onStart() {

    }

    @Override
    public void onStop() {

    }

    @Override
    public void onDestroy() {
        if (!TextUtils.isEmpty(mGroupTag)) {
            synchronized (mListMap) {
                List<Call> callList = mListMap.get(mGroupTag);
                if (callList == null) {
                    return;
                }
                for (Call call : callList) {
                    call.cancel();
                }
                mListMap.remove(mGroupTag);
            }
        }

    }

}
